package com.iplant.ams.controller.ams;

import com.iplant.ams.service.basicenum.ams.AMSFixedAssetsType;
import com.iplant.ams.service.basicenum.ams.fxt.AMSFrockType;
import com.iplant.ams.service.basicenum.ams.fxt.AMSMeasureType;
import com.iplant.ams.service.po.ams.asset.AMSAssetStandardModel;
import com.iplant.ams.service.po.ams.fxt.AMSFrockTool;
import com.iplant.ams.service.po.ams.fxt.AMSMeasureTool;
import com.iplant.ams.service.po.dms.DMSDeviceModel;
import com.iplant.ams.service.po.dms.DMSDeviceType;
import com.iplant.base.po.Pagination;
import com.iplant.base.po.ServiceResult;
import com.iplant.base.utils.RetCode;
import com.iplant.base.utils.annotation.trace.TraceAPI;
import com.iplant.base.utils.annotation.trace.TraceModuleAPI;
import com.iplant.base.utils.serializer.CloneTool;
import com.iplant.base.utils.general.StringUtils;
import com.iplant.base.utils.sql.orm.ORMUtils;
import com.iplant.base.utils.sql.orm.PoService;
import com.iplant.basic.controller.BasicController;
import com.iplant.basic.service.po.bms.BMSEmployee;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author femi
 * 2023-7-7 14:33:00
 */
@TraceModuleAPI("资产标准型号")
@RestController
@RequestMapping("/api/AMSAssetStandardModel")
public class AMSAssetStandardModelController extends BasicController<AMSAssetStandardModel> {
    private static final Logger logger = LoggerFactory.getLogger(AMSAssetStandardModelController.class);

    PoService<DMSDeviceModel> DeviceModelService;

    PoService<DMSDeviceType> DeviceTypeService;
    PoService<AMSFrockTool> FrockToolService;

    PoService<AMSMeasureTool> MeasureToolService;
    
    public AMSAssetStandardModelController() {
        super(AMSAssetStandardModel.class);
        DeviceModelService = ORMUtils.GetPoService(DMSDeviceModel.class);

        FrockToolService = ORMUtils.GetPoService(AMSFrockTool.class);
        DeviceTypeService= ORMUtils.GetPoService(DMSDeviceType.class);

        MeasureToolService = ORMUtils.GetPoService(AMSMeasureTool.class);
    }

    /**
     * 新增或更新
     */
    @TraceAPI(value = "新增或更新")
    @PostMapping("/Update")
    public Object Update(HttpServletRequest request, @RequestBody Map<String, Object> wParam) {
        Object wResult;
        try {
            BMSEmployee wLoginUser = GetSession(request);


            ServiceResult<AMSAssetStandardModel> wServiceResult = mPoService.UpdateSelectPo(wLoginUser, wParam);

            if (wServiceResult != null && StringUtils.isEmpty(wServiceResult.getFaultCode())
                    && wServiceResult.Result != null && wServiceResult.Result.ID > 0 ) {
               
                Map<String, Object> wParasMap;
                switch (AMSFixedAssetsType.getEnumType(wServiceResult.Result.TypeEnum)) {


                    case Device:
                        wParasMap= new HashMap<>();
                        wParasMap.put("StandardModelID",wServiceResult.Result.ID);
                        ServiceResult<DMSDeviceModel> wDMSDeviceModelServiceResult = DeviceModelService.SelectPO(wLoginUser, wParasMap);
                        if (StringUtils.isNotEmpty(wDMSDeviceModelServiceResult.getFaultCode())) {
                            wServiceResult.FaultCode += wDMSDeviceModelServiceResult.getFaultCode();
                            wResult = GetResult(RetCode.SERVER_CODE_ERR, wServiceResult.getFaultCode());
                            return wResult;
                        }

                        if(wDMSDeviceModelServiceResult.Result==null||wDMSDeviceModelServiceResult.Result.ID<=0){
                            DMSDeviceType wDMSDeviceType = new DMSDeviceType();
                            wDMSDeviceType.Name = "默认";
                            wDMSDeviceType.ID = 1;
                            ServiceResult<List<DMSDeviceType>> wDMSDeviceTypeServiceResult = DeviceTypeService.SelectPOList(wLoginUser, null, Pagination.getNewMaxSize());
                            if (wDMSDeviceTypeServiceResult != null && wDMSDeviceTypeServiceResult.Result != null && wDMSDeviceTypeServiceResult.Result.size() > 0) {
                                wDMSDeviceType = wDMSDeviceTypeServiceResult.Result.get(0);
                            }

                            DMSDeviceModel wDMSDeviceModel =  new DMSDeviceModel(wServiceResult.Result, wDMSDeviceType);
                            wDMSDeviceModel.setUserInfo(wLoginUser);
                            ServiceResult<Integer> wServiceResultInt = DeviceModelService.UpdatePo(wLoginUser, wDMSDeviceModel);
                            if (StringUtils.isNotEmpty(wServiceResultInt.getFaultCode())) {
                                wServiceResult.FaultCode += wServiceResultInt.getFaultCode();
                            }
                        }
                        break;
                    case Frock:
                        wParasMap= new HashMap<>();
                        wParasMap.put("StandardModelID",wServiceResult.Result.ID);
                        ServiceResult<AMSFrockTool> wDMSFrockToolServiceResult = FrockToolService.SelectPO(wLoginUser, wParasMap);
                        if (StringUtils.isNotEmpty(wDMSFrockToolServiceResult.getFaultCode())) {
                            wServiceResult.FaultCode += wDMSFrockToolServiceResult.getFaultCode();
                            wResult = GetResult(RetCode.SERVER_CODE_ERR, wServiceResult.getFaultCode());
                            return wResult;
                        }

                        if(wDMSFrockToolServiceResult.Result==null||wDMSFrockToolServiceResult.Result.ID<=0){

                            AMSFrockTool wDMSFrockTool =  new AMSFrockTool(wServiceResult.Result, AMSFrockType.MJ);
                            wDMSFrockTool.setUserInfo(wLoginUser);
                            ServiceResult<Integer> wServiceResultInt = FrockToolService.UpdatePo(wLoginUser, wDMSFrockTool);
                            if (StringUtils.isNotEmpty(wServiceResultInt.getFaultCode())) {
                                wServiceResult.FaultCode += wServiceResultInt.getFaultCode();
                            }
                        }
                        break;
                    case Measure:
                        wParasMap= new HashMap<>();
                        wParasMap.put("StandardModelID",wServiceResult.Result.ID);
                        ServiceResult<AMSMeasureTool> wDMSMeasureToolServiceResult = MeasureToolService.SelectPO(wLoginUser, wParasMap);
                        if (StringUtils.isNotEmpty(wDMSMeasureToolServiceResult.getFaultCode())) {
                            wServiceResult.FaultCode += wDMSMeasureToolServiceResult.getFaultCode();
                            wResult = GetResult(RetCode.SERVER_CODE_ERR, wServiceResult.getFaultCode());
                            return wResult;
                        }

                        if(wDMSMeasureToolServiceResult.Result==null||wDMSMeasureToolServiceResult.Result.ID<=0){

                            AMSMeasureTool wDMSMeasureTool =  new AMSMeasureTool(wServiceResult.Result, AMSMeasureType.Universal);
                            wDMSMeasureTool.setUserInfo(wLoginUser);
                            ServiceResult<Integer> wServiceResultInt = MeasureToolService.UpdatePo(wLoginUser, wDMSMeasureTool);
                            if (StringUtils.isNotEmpty(wServiceResultInt.getFaultCode())) {
                                wServiceResult.FaultCode += wServiceResultInt.getFaultCode();
                            }
                        }
                        break;
                    case Default:
                        break;
                }

               
            }

            if (StringUtils.isEmpty(wServiceResult.getFaultCode())) {
                wResult = GetResult(RetCode.SERVER_CODE_SUC, "", null, wServiceResult.getResult());
            } else {
                wResult = GetResult(RetCode.SERVER_CODE_ERR, wServiceResult.getFaultCode());
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
            wResult = GetResult(RetCode.SERVER_CODE_ERR, ex.toString());
        }
        return wResult;
    }


    /**
     * 新增或更新
     */
    @TraceAPI("批量新增或更新")
    @PostMapping("/UpdateList")
    public Object UpdateList(HttpServletRequest request, @RequestBody Map<String, Object> wParam) {
        Object wResult;
        try {
            BMSEmployee wLoginUser = GetSession(request);


            if (!wParam.containsKey("data")) {
                wResult = GetResult(RetCode.SERVER_CODE_ERR, RetCode.SERVER_RST_ERROR_OUT);
                return wResult;
            }

            List<AMSAssetStandardModel> wList = CloneTool.CloneArray(wParam.get("data"), AMSAssetStandardModel.class);

            if(wList==null||wList.size()==0){
                wResult = GetResult(RetCode.SERVER_CODE_ERR, RetCode.SERVER_RST_ERROR_OUT);
                return wResult;
            }

            ServiceResult<List<DMSDeviceModel>> wDMSDeviceModelServiceResult = DeviceModelService.SelectPOList(wLoginUser, null,Pagination.getNewMaxSize());
            if (StringUtils.isNotEmpty(wDMSDeviceModelServiceResult.getFaultCode())) {
                wResult = GetResult(RetCode.SERVER_CODE_ERR, wDMSDeviceModelServiceResult.getFaultCode());
                return wResult;
            }

            Map<Integer,DMSDeviceModel> wDMSDeviceModelMap=new HashMap<>();
            if(wDMSDeviceModelServiceResult.Result!=null&&wDMSDeviceModelServiceResult.Result.size()>0){
                wDMSDeviceModelMap=wDMSDeviceModelServiceResult.Result.stream().collect(Collectors.toMap(p->p.StandardModelID,q->q,(o1,o2)->o2));
            }

            Map<Integer, AMSFrockTool> wAMSFrockToolMap = new HashMap<>();

            ServiceResult<List<AMSFrockTool>> wAMSFrockToolServiceResult =
                    FrockToolService.SelectPOList(wLoginUser, null,
                            Pagination.getNewMaxSize());
            if (wAMSFrockToolServiceResult != null && wAMSFrockToolServiceResult.Result != null && wAMSFrockToolServiceResult.Result.size() > 0) {
                wAMSFrockToolMap =
                        wAMSFrockToolServiceResult.Result.stream().collect(Collectors.toMap(AMSFrockTool::getStandardModelID, Function.identity(), (o1, o2) -> o2));
            }


            Map<Integer, AMSMeasureTool> wAMSMeasureToolMap = new HashMap<>();

            ServiceResult<List<AMSMeasureTool>> wAMSMeasureToolServiceResult =
                    MeasureToolService.SelectPOList(wLoginUser, null,
                            Pagination.getNewMaxSize());
            if (wAMSMeasureToolServiceResult != null && wAMSMeasureToolServiceResult.Result != null && wAMSMeasureToolServiceResult.Result.size() > 0) {
                wAMSMeasureToolMap =
                        wAMSMeasureToolServiceResult.Result.stream().collect(Collectors.toMap(AMSMeasureTool::getStandardModelID, Function.identity(), (o1, o2) -> o2));
            }
            

            DMSDeviceType wDMSDeviceType = new DMSDeviceType();
            wDMSDeviceType.Name = "默认";
            wDMSDeviceType.ID = 1;
            ServiceResult<List<DMSDeviceType>> wDMSDeviceTypeServiceResult = DeviceTypeService.SelectPOList(wLoginUser, null, Pagination.getNewMaxSize());
            if (wDMSDeviceTypeServiceResult != null && wDMSDeviceTypeServiceResult.Result != null && wDMSDeviceTypeServiceResult.Result.size() > 0) {
                wDMSDeviceType = wDMSDeviceTypeServiceResult.Result.get(0);
            }

            ServiceResult<Integer> wServiceResult = new ServiceResult<>();
            ServiceResult<AMSAssetStandardModel> wAMSAssetStandardModelServiceResult = new ServiceResult<>();
            DMSDeviceModel wDMSDeviceModel;
            AMSFrockTool wAMSFrockTool;
            AMSMeasureTool wAMSMeasureTool;
            AMSAssetStandardModel wAssetStandardModel;
            for (AMSAssetStandardModel wAMSAssetStandardModel : wList) {

                wAMSAssetStandardModel.setUserInfo(wLoginUser);
                wAMSAssetStandardModelServiceResult = mPoService.UpdateSelectPo(wLoginUser, wAMSAssetStandardModel);

                if (StringUtils.isNotEmpty(wAMSAssetStandardModelServiceResult.getFaultCode())) {
                    wServiceResult.FaultCode+=wAMSAssetStandardModelServiceResult.getFaultCode();
                    break;
                }
                if(wAMSAssetStandardModelServiceResult.Result==null||wAMSAssetStandardModelServiceResult.Result.ID<=0){
                    continue;
                }
                wAssetStandardModel=wAMSAssetStandardModelServiceResult.Result;

                switch (AMSFixedAssetsType.getEnumType(wAssetStandardModel.TypeEnum)) {


                    case Device:
                        if(wDMSDeviceModelMap.containsKey(wAssetStandardModel.ID))
                            continue;

                        wDMSDeviceModel = new DMSDeviceModel(wAssetStandardModel, wDMSDeviceType);
                        wDMSDeviceModel.setUserInfo(wLoginUser);
                        wServiceResult = DeviceModelService.UpdateCheckPo(wLoginUser, wDMSDeviceModel);
                        if (StringUtils.isNotEmpty(wServiceResult.getFaultCode())) {
                            break;
                        }
                        wDMSDeviceModelMap.put(wAssetStandardModel.ID,wDMSDeviceModel);
                        break;
                    case Frock:
                        if(wAMSFrockToolMap.containsKey(wAssetStandardModel.ID))
                            continue;

                        wAMSFrockTool = new AMSFrockTool(wAssetStandardModel, AMSFrockType.MJ);
                        wAMSFrockTool.setUserInfo(wLoginUser);
                        wServiceResult = FrockToolService.UpdateCheckPo(wLoginUser, wAMSFrockTool);
                        if (StringUtils.isNotEmpty(wServiceResult.getFaultCode())) {
                            break;
                        }
                        wAMSFrockToolMap.put(wAssetStandardModel.ID,wAMSFrockTool);
                        break;
                    case Measure:
                        if(wAMSMeasureToolMap.containsKey(wAssetStandardModel.ID))
                            continue;

                        wAMSMeasureTool = new AMSMeasureTool(wAssetStandardModel, AMSMeasureType.Universal);
                        wAMSMeasureTool.setUserInfo(wLoginUser);
                        wServiceResult = MeasureToolService.UpdateCheckPo(wLoginUser, wAMSMeasureTool);
                        if (StringUtils.isNotEmpty(wServiceResult.getFaultCode())) {
                            break;
                        }
                        wAMSMeasureToolMap.put(wAssetStandardModel.ID,wAMSMeasureTool);
                        break;
                    case Default:
                        break;
                }

            }

            if (StringUtils.isEmpty(wServiceResult.getFaultCode())) {
                wResult = GetResult(RetCode.SERVER_CODE_SUC, "", wList, null);
            } else {
                wResult = GetResult(RetCode.SERVER_CODE_ERR, wServiceResult.getFaultCode());
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
            wResult = GetResult(RetCode.SERVER_CODE_ERR, ex.toString());
        }
        return wResult;
    }


}
